home *** CD-ROM | disk | FTP | other *** search
/ The Atari Compendium / The Atari Compendium (Toad Computers) (1994).iso / files / prgtools / mint / shells / tcshsrc.zoo / tcsh / tc.prompt.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-10-25  |  9.6 KB  |  400 lines

  1. /* $Header: /home/hyperion/mu/christos/src/sys/tcsh-6.00/RCS/tc.prompt.c,v 3.2 1991/07/15 19:37:24 christos Exp $ */
  2. /*
  3.  * tc.prompt.c: Prompt printing stuff
  4.  */
  5. /*-
  6.  * Copyright (c) 1980, 1991 The Regents of the University of California.
  7.  * All rights reserved.
  8.  *
  9.  * Redistribution and use in source and binary forms, with or without
  10.  * modification, are permitted provided that the following conditions
  11.  * are met:
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in the
  16.  *    documentation and/or other materials provided with the distribution.
  17.  * 3. All advertising materials mentioning features or use of this software
  18.  *    must display the following acknowledgement:
  19.  *    This product includes software developed by the University of
  20.  *    California, Berkeley and its contributors.
  21.  * 4. Neither the name of the University nor the names of its contributors
  22.  *    may be used to endorse or promote products derived from this software
  23.  *    without specific prior written permission.
  24.  *
  25.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  26.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  27.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  28.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  29.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  30.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  31.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  32.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  33.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  34.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  35.  * SUCH DAMAGE.
  36.  */
  37. #include "config.h"
  38. RCSID("$Id: tc.prompt.c,v 3.2 1991/07/15 19:37:24 christos Exp $")
  39.  
  40. #include "sh.h"
  41. #include "ed.h"
  42.  
  43. /*
  44.  * kfk 21oct1983 -- add @ (time) and / ($cwd) in prompt.
  45.  * PWP 4/27/87 -- rearange for tcsh.
  46.  * mrdch@com.tau.edu.il 6/26/89 - added ~, T and .# - rearanged to switch()
  47.  *                 instead of if/elseif
  48.  */
  49.  
  50. char   *month_list[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
  51.             "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  52. void
  53. printprompt(promptno, str)
  54.     int     promptno;
  55.     Char   *str;
  56. {
  57.     Char   *p, *z, *q;
  58.     register Char attributes = 0;
  59.     static int print_prompt_did_ding = 0;
  60.     register char *cz;
  61.     struct tm *t;
  62.     time_t  lclock;
  63.     Char    buff[BUFSIZ];
  64.     Char   *cp;
  65.  
  66.     (void) time(&lclock);
  67.     t = localtime(&lclock);
  68.  
  69.     PromptBuf[0] = '\0';
  70.     p = PromptBuf;
  71.     switch (promptno) {
  72.     default:
  73.     case 0:
  74.     cp = value(STRprompt);
  75.     break;
  76.     case 1:
  77.     cp = value(STRprompt2);
  78.     break;
  79.     case 2:
  80.     cp = value(STRprompt3);
  81.     break;
  82.     }
  83.  
  84.     for (; *cp; cp++) {
  85.     if (*cp == '%') {
  86.         cp++;
  87.         switch (*cp) {
  88.         case 'R':
  89.         if (str != NULL)
  90.             while (*str)
  91.             *p++ = attributes | *str++;
  92.         break;
  93.         case '#':
  94.         *p++ = attributes | ((uid == 0) ? '#' : '>');
  95.         break;
  96.         case '!':
  97.         case 'h':
  98.         Itoa(eventno + 1, buff);
  99.         for (z = buff; *z; z++)
  100.             *p++ = attributes | *z;
  101.         break;
  102.         case 'T':        /* 24 hour format     */
  103.         case '@':
  104.         case 't':        /* 12 hour am/pm format */
  105.         {
  106.             char    ampm = 'a';
  107.             int     hr = t->tm_hour;
  108.  
  109.             /* addition by Hans J. Albertsson */
  110.             /* and another adapted from Justin Bur */
  111.             if (adrof(STRampm) || *cp != 'T') {
  112.             if (hr >= 12) {
  113.                 if (hr > 12)
  114.                 hr -= 12;
  115.                 ampm = 'p';
  116.             }
  117.             else if (hr == 0)
  118.                 hr = 12;
  119.             }        /* else do a 24 hour clock */
  120.  
  121.             /* "DING!" stuff by Hans also */
  122.             if (t->tm_min || print_prompt_did_ding
  123.              /* || !adrof(STRprompt_ding) */ ) {
  124.             if (t->tm_min)
  125.                 print_prompt_did_ding = 0;
  126.             Itoa(hr, buff);
  127.             *p++ = attributes | buff[0];
  128.             if (buff[1])
  129.                 *p++ = attributes | buff[1];
  130.             *p++ = attributes | ':';
  131.             Itoa(t->tm_min, buff);
  132.             if (buff[1]) {
  133.                 *p++ = attributes | buff[0];
  134.                 *p++ = attributes | buff[1];
  135.             }
  136.             else {
  137.                 *p++ = attributes | '0';
  138.                 *p++ = attributes | buff[0];
  139.             }
  140.             if (adrof(STRampm) || *cp != 'T') {
  141.                 *p++ = attributes | ampm;
  142.                 *p++ = attributes | 'm';
  143.             }
  144.             }
  145.             else {    /* we need to ding */
  146.             int     i = 0;
  147.  
  148.             (void) Strcpy(buff, STRDING);
  149.             while (buff[i]) {
  150.                 *p++ = attributes | buff[i++];
  151.             }
  152.             print_prompt_did_ding = 1;
  153.             }
  154.         }
  155.         break;
  156.  
  157.         case 'M':
  158.         /*
  159.          * Bug pointed out by Laurent Dami <dami@cui.unige.ch>: don't
  160.          * derefrence that NULL (if HOST is not set)...
  161.          */
  162.         if ((cz = getenv("HOST")) != NULL)
  163.             while (*cz)
  164.             *p++ = attributes | *cz++;
  165.         break;
  166.  
  167.         case 'm':
  168.         if ((cz = getenv("HOST")) != NULL)
  169.             while (*cz && *cz != '.')
  170.             *p++ = attributes | *cz++;
  171.         break;
  172.  
  173.         case '~':        /* show ~ whenever possible - a la dirs */
  174.         {
  175.             static Char *olddir = 0, *olduser = 0, *oldpath = 0;
  176.  
  177.             if (!(z = value(STRcwd)))
  178.             break;    /* no cwd, so don't do anything */
  179.             /*
  180.              * Have we changed directory?
  181.              */
  182.             if (olddir != z) {
  183.             oldpath = olddir = z;
  184.             olduser = getusername(&oldpath);
  185.             }
  186.             if (olduser) {
  187.             *p++ = attributes | '~';
  188.             for (q = olduser; *q; *p++ = attributes | *q++);
  189.             for (z = oldpath; *z; *p++ = attributes | *z++);
  190.             break;
  191.             }
  192.         }
  193.         /* fall through if ~ not matched */
  194.         case '/':
  195.         case 'd':
  196.         if (z = value(STRcwd)) {
  197.             while (*z)
  198.             *p++ = attributes | *z++;
  199.         }
  200.         break;
  201.         case '.':
  202.         case 'c':
  203.         case 'C':
  204.         {
  205.             register int j, k;
  206.             Char    scp;
  207.  
  208.             scp = *cp;
  209.             /* option to determine fix number of dirs from path */
  210.             if (*(cp + 1) >= '1' && *(cp + 1) <= '9') {
  211.             j = *(cp + 1) - '0';
  212.             cp++;
  213.             }
  214.             else {
  215.             j = 1;
  216.             }
  217.             if (!(z = value(STRcwd)))
  218.             break;
  219.             (void) Strcpy(buff, z);
  220.             if (!buff[1]) {    /* if CWD == / */
  221.             *p++ = attributes | buff[0];
  222.             }
  223.             else {
  224.             if ((scp != 'C') && (q = value(STRhome)) &&
  225.                 Strncmp(buff, q, (k = Strlen(q))) == 0 &&
  226.                 (buff[k] == '/' || buff[k] == '\0')) {
  227.                 buff[--k] = '~';
  228.                 q = &buff[k];
  229.             }
  230.             else
  231.                 q = buff;
  232.             for (z = q; *z; z++);    /* find the end */
  233.             while (j-- > 0) {
  234.                 while ((z > q) && (*z != '/'))
  235.                 z--;    /* back up */
  236.                 if (j && z > q)
  237.                 z--;
  238.             }
  239.             if (*z == '/' && z != q)
  240.                 z++;
  241.             while (*z)
  242.                 *p++ = attributes | *z++;
  243.             }
  244.         }
  245.         break;
  246.         case 'n':
  247.         if (z = value(STRuser))
  248.             while (*z)
  249.             *p++ = attributes | *z++;
  250.         break;
  251.         case 'l':
  252.         if (z = value(STRtty))
  253.             while (*z)
  254.             *p++ = attributes | *z++;
  255.         break;
  256.         case 'w':
  257.         for (cz = month_list[t->tm_mon]; *cz;)
  258.             *p++ = attributes | *cz++;
  259.         *p++ = attributes | ' ';
  260.         Itoa(t->tm_mday, buff);
  261.         *p++ = attributes | buff[0];
  262.         if (buff[1])
  263.             *p++ = attributes | buff[1];
  264.         break;
  265.         case 'W':
  266.         Itoa(t->tm_mon + 1, buff);
  267.         if (buff[1]) {
  268.             *p++ = attributes | buff[0];
  269.             *p++ = attributes | buff[1];
  270.         }
  271.         else {
  272.             *p++ = attributes | '0';
  273.             *p++ = attributes | buff[0];
  274.         }
  275.         *p++ = attributes | '/';
  276.  
  277.         Itoa(t->tm_mday, buff);
  278.         if (buff[1]) {
  279.             *p++ = attributes | buff[0];
  280.             *p++ = attributes | buff[1];
  281.         }
  282.         else {
  283.             *p++ = attributes | '0';
  284.             *p++ = attributes | buff[0];
  285.         }
  286.         *p++ = attributes | '/';
  287.  
  288.         Itoa(t->tm_year, buff);
  289.         if (buff[1]) {
  290.             *p++ = attributes | buff[0];
  291.             *p++ = attributes | buff[1];
  292.         }
  293.         else {
  294.             *p++ = attributes | '0';
  295.             *p++ = attributes | buff[0];
  296.         }
  297.         break;
  298.         case 'D':
  299.         Itoa(t->tm_year, buff);
  300.         if (buff[1]) {
  301.             *p++ = attributes | buff[0];
  302.             *p++ = attributes | buff[1];
  303.         }
  304.         else {
  305.             *p++ = attributes | '0';
  306.             *p++ = attributes | buff[0];
  307.         }
  308.         *p++ = attributes | '-';
  309.  
  310.         Itoa(t->tm_mon + 1, buff);
  311.         if (buff[1]) {
  312.             *p++ = attributes | buff[0];
  313.             *p++ = attributes | buff[1];
  314.         }
  315.         else {
  316.             *p++ = attributes | '0';
  317.             *p++ = attributes | buff[0];
  318.         }
  319.         *p++ = attributes | '-';
  320.  
  321.         Itoa(t->tm_mday, buff);
  322.         if (buff[1]) {
  323.             *p++ = attributes | buff[0];
  324.             *p++ = attributes | buff[1];
  325.         }
  326.         else {
  327.             *p++ = attributes | '0';
  328.             *p++ = attributes | buff[0];
  329.         }
  330.         break;
  331.         case 'S':        /* start standout */
  332.         attributes |= STANDOUT;
  333.         break;
  334.         case 'B':        /* start bold */
  335.         attributes |= BOLD;
  336.         break;
  337.         case 'U':        /* start underline */
  338.         attributes |= UNDER;
  339.         break;
  340.         case 's':        /* end standout */
  341.         attributes &= ~STANDOUT;
  342.         break;
  343.         case 'b':        /* end bold */
  344.         attributes &= ~BOLD;
  345.         break;
  346.         case 'u':        /* end underline */
  347.         attributes &= ~UNDER;
  348.         break;
  349.         case 'L':
  350.         ClearToBottom();
  351.         break;
  352.         case '?':
  353.         if (z = value(STRstatus))
  354.             while (*z)
  355.             *p++ = attributes | *z++;
  356.         break;
  357.         case '%':
  358.         *p++ = attributes | '%';
  359.         break;
  360.         case '{':        /* literal characters start */
  361. #if LITERAL == 0
  362.         /*
  363.          * No literal capability, so skip all chars in the literal
  364.          * string
  365.          */
  366.         while (*cp != '\0' && (*cp != '%' || cp[1] != '}'))
  367.             cp++;
  368. #endif                /* LITERAL == 0 */
  369.         attributes |= LITERAL;
  370.         break;
  371.         case '}':        /* literal characters end */
  372.         attributes &= ~LITERAL;
  373.         break;
  374.         default:
  375.         *p++ = attributes | '%';
  376.         *p++ = attributes | *cp;
  377.         break;
  378.         }
  379.     }
  380.     else if (*cp == '\\' | *cp == '^') {
  381.         *p++ = attributes | parseescape(&cp);
  382.     }
  383.     else if (*cp == '!') {    /* EGS: handle '!'s in prompts */
  384.         Itoa(eventno + 1, buff);
  385.         for (z = buff; *z; z++)
  386.         *p++ = attributes | *z;
  387.     }
  388.     else {
  389.         *p++ = attributes | *cp;    /* normal character */
  390.     }
  391.     }
  392.     *p = '\0';
  393.     if (!editing) {
  394.     for (z = PromptBuf; z < p; z++)
  395.         (void) putraw(*z);
  396.     SetAttributes(0);
  397.     flush();
  398.     }
  399. }
  400.